﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Threading;
using System.Reflection;
using System.IO;
using System.Diagnostics;
using System.Runtime.InteropServices;
using System.Media;
using System.Data.OleDb;


namespace WindowsFormsApplication5
{
    public class IntelektMove
    {
        private const int up = 3, right = 2, left = 1, down = 4;
        private const int  H = 55, W = 65;
        private int[,] array = new int[H, W];
        private Data data;
        private int tempx, tempy;
        private    int temp_direct;
        private    int iam;
        private   Rectangle temp1 = new Rectangle();
        string dir1 = " ";
        string fulldir1 = " ";
        private Draw draw;
        private List<Brick> listbrick;
        private List<PictureBox> enemysDraw;
        private Logic logic;
        private List<Water> listwater;
        private List<Tank> enemys;
        private Rectangle temp;
        private int indexer = 0;
        private Rectangle form;
        private Random rand;

        public IntelektMove(string dir, List<Brick> listbrick, List<Water> listwater, Rectangle form, PictureBox pic, List<Tank> enemys, List<PictureBox> enemysDraw)
        {
            data = new Data();
            temp1.Size = new Size(data.tank_width, data.tank_height);
            this.dir1 = String.Copy(dir);
            draw = new Draw(pic);
            this.listbrick = listbrick;
            logic = new Logic();
            this.listwater = listwater;
            this.form = form;
            this.enemys = enemys;
            this.enemysDraw = enemysDraw;
            rand = new Random();

        }

        public bool way(int ax, int ay, int bx, int by, ref List<Point> trace, int variant)
        {
            Rectangle temptank = new Rectangle();
            temptank.Size = new Size(data.tank_width, data.tank_height);
            temptank.Location = new Point(ax, ay);


            int direct = 0;
            int iam = variant;
            int len;
            int tempx = 0, tempy = 0, tempbx = 0, tempby = 0;



            // function
            const int W = 65;         // ширина рабочего поля
            const int H = 55;         // высота рабочего поля
            const int WALL = -1;         // непроходимая ячейка
            const int BLANK = -1;

            int[] dx = new int[] { 10, 0, -10, 0 };
            int[] dy = new int[] { 0, 10, 0, -10 };
            int d, x = 0, y = 0, k;
            bool stop;
            d = 0;

            array[ay / 10, ax / 10] = 0;

            k = 0;
            //  try
            {
                //   sw = new StreamWriter("D:\\Test.txt");
                do
                {
                    stop = true;
                    for (y = 0; y < H; ++y)
                    {
                        for (x = 0; x < W; ++x)
                        {

                            if (array[y, x] == d)
                            {

                                for (k = 0; k < 4; ++k)
                                {

                                    temptank.Location = new Point(x * 10 + dx[k], y * 10 + dy[k]);

                                    switch (k)
                                    {
                                        case (0): { direct = 2; break; }
                                        case (1): { direct = 4; break; }
                                        case (2): { direct = 1; break; }
                                        case (3): { direct = 3; break; }
                                    }
                                    if (((temptank.Location.Y / 10) < 0) || ((temptank.Location.X / 10) < 0))
                                        break;

                                    if ((array[temptank.Location.Y / 10, temptank.Location.X / 10] == (-1))
                                       && (logic.Collision(temptank, form, direct))
                                        && (logic.CheckBrick(temptank, 1, 0, listbrick) < 0)
                                             && ((logic.CheckEnemy(temptank, 1, iam, 0, enemys) < 0)
                                                 || (logic.CheckEnemy(temptank, 1, iam, 0, enemys) == 0))
                                                  && (logic.CheckWater(temptank, 1, 0, listwater) < 0))
                                    {
                                        stop = false;



                                        array[temptank.Location.Y / 10, temptank.Location.X / 10] = (d + 1);

                                    }
                                }
                            }

                        }

                    }


                    d++;

                } while (!stop && (array[by / 10, bx / 10] == BLANK));

            }



            len = array[by / 10, bx / 10];
            x = bx / 10;
            y = by / 10;
            d = len;
            while (d > 0)
            {

                trace.Add(new Point(x * 10, y * 10));

                d--;

                for (k = 0; k < 4; ++k)
                    if (array[(y + (dy[k] / 10)), (x + (dx[k] / 10))] == d)
                    {

                        x = x + (dx[k] / 10);
                        y = y + (dy[k] / 10);
                        break;
                    }
            }


            return true;

        }

        public void cleararray()
        {
            for (int i = 0; i < array.GetLength(0); i++)
            {
                for (int j = 0; j < array.GetLength(1); j++)
                {
                    array[i, j] = -1;
                }
            }
        }

        public void MoveRandom()
        {
            foreach (Tank enemy in enemys)
            {
                if (enemy.MyTank!= 1)
                {
                    iam = enemys.IndexOf(enemy);
                    Console.WriteLine("Enemy " + enemy.MyTank);
                    switch (enemy.Direct)
                    {
                        case (up): { temp1.Location = new Point(enemy.tank.Location.X, enemy.tank.Location.Y - data.speed); }; break;
                        case (down): { temp1.Location = new Point(enemy.tank.Location.X, enemy.tank.Location.Y + data.speed); }; break;
                        case (left): { temp1.Location = new Point(enemy.tank.Location.X - data.speed, enemy.tank.Location.Y); }; break;
                        case (right): { temp1.Location = new Point(enemy.tank.Location.X + data.speed, enemy.tank.Location.Y); }; break;
                    }
                    if ((logic.Collision( enemy.tank,  form, enemy.Direct)) && 
                        (logic.CheckBrick( temp1, 1, 0, listbrick) < 0) 
                        && (logic.CheckEnemy( temp1, 1, iam, 0, enemys) < 0)
                        && (logic.CheckWater( temp1, 1, 0, listwater) < 0))
                    {                       
                        switch (enemy.Direct)
                        {
                            case (up):
                                {
                                    dir1 = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location);
                                    if (enemy.Type == data.light)
                                    {
                                        fulldir1 = Path.Combine(dir1, "2.bmp");
                                    }
                                    else
                                    {
                                        fulldir1 = Path.Combine(dir1, "heavytank.bmp");
                                    }
                                    //Bitmap mybit1 = new Bitmap(fulldir1);
                                    //mybit1.MakeTransparent(Color.FromArgb(255, 255, 255));
                                    //enemy.picbox.Image = mybit1;
                                }; break;
                            case (down):
                                {
                                    dir1 = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location);
                                    if (enemy.Type == data.light)
                                    {
                                        fulldir1 = Path.Combine(dir1, "4.bmp");
                                    }
                                    else
                                    {
                                        fulldir1 = Path.Combine(dir1, "hv2.bmp");
                                    }
                                    //Bitmap mybit1 = new Bitmap(fulldir1);
                                    //mybit1.MakeTransparent(Color.FromArgb(255, 255, 255));
                                    //enemy.picbox.Image = mybit1;
                             }; break;
                            case (left):
                                {
                                    dir1 = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location);
                                    if (enemy.Type == data.light)
                                    {
                                        fulldir1 = Path.Combine(dir1, "5.bmp");
                                    }
                                    else
                                    {
                                        fulldir1 = Path.Combine(dir1, "hv3.bmp");
                                    }
                                    //Bitmap mybit1 = new Bitmap(fulldir1);
                                    //mybit1.MakeTransparent(Color.FromArgb(255, 255, 255));
                                    //enemy.picbox.Image = mybit1;
                                }; break;
                            case (right):
                                {
                                    dir1 = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location);
                                    if (enemy.Type == data.light)
                                    {
                                        fulldir1 = Path.Combine(dir1, "3.bmp");
                                    }
                                    else
                                    {
                                        fulldir1 = Path.Combine(dir1, "hv1.bmp");
                                    }
                                    //Bitmap mybit1 = new Bitmap(fulldir1);
                                    //mybit1.MakeTransparent(Color.FromArgb(255, 255, 255));
                                    //enemy.picbox.Image = mybit1;
                                }; break;
                        }

                        draw.Image( enemysDraw, fulldir1, enemy.tank);
                    // Console.WriteLine("Dozvil ryx");
                        if (enemy.Type == 3)
                        enemy.tank = logic.Move( enemy.tank, enemy.Direct, data.SpeedEnemyHeavy);
                        else
                            enemy.tank = logic.Move( enemy.tank, enemy.Direct, data.speed_enemy);
                        draw.MoveDraw( enemysDraw, enemy.tank, enemys.IndexOf(enemy));
                    }
                    else
                    {
                        do
                        {
                            temp_direct = rand.Next(1, 5);
                            enemy.Direct = temp_direct;
                            switch (enemy.Direct)
                            {
                                case (up): { temp1.Location = new Point(enemy.tank.Location.X, enemy.tank.Location.Y - data.speed); }; break;
                                case (down): { temp1.Location = new Point(enemy.tank.Location.X, enemy.tank.Location.Y + data.speed); }; break;
                                case (left): { temp1.Location = new Point(enemy.tank.Location.X - data.speed, enemy.tank.Location.Y); }; break;
                                case (right): { temp1.Location = new Point(enemy.tank.Location.X + data.speed, enemy.tank.Location.Y); }; break;
                            }

                        } while ((temp_direct != enemy.Direct) && 
                            logic.Collision(enemy.tank, form, enemy.Direct)
                                && (logic.CheckBrick( temp1, 1, 0, listbrick) < 0)
                            && (logic.CheckEnemy( temp1, 1, iam, 0, enemys) < 0)
                            && (logic.CheckWater(temp1, 1, 0, listwater) < 0));

                    }
                }

            }

        }

        public void MoveWave(List<Tank> enemys, List<PictureBox> enemysDraw)
        {
            int index = 0;

             if (indexer == 0)
            {
                
                indexer++;
            }
            temp_direct = 0;

            foreach (Tank enemy in enemys)
            {
                index++;
               
                iam = enemys.IndexOf(enemy);
                if (enemy.MyTank != 1)
                {
                    if (enemy.trace.Count != 0)
                    {

                        temp.Location = new Point(enemy.trace[enemy.trace.Count - 1].X, enemy.trace[enemy.trace.Count - 1].Y);
                        if (logic.CheckEnemy(temp, 1, iam, 0, enemys) < 0)
                        {
                            tempx = temp.Location.X - enemy.tank.Location.X;
                            tempy = temp.Location.Y - enemy.tank.Location.Y;
                            if (tempx > 0) { temp_direct = right; }
                            if (tempx < 0) { temp_direct = left; }
                            if (tempy < 0) { temp_direct = up; }
                            if (tempy > 0) { temp_direct = down; }

                            switch (temp_direct)
                            {
                                case (up):
                                    {
                                        enemy.Direct = data.up;
                                        dir1 = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location);
                                        if (enemy.Type == data.light)
                                        {
                                            fulldir1 = Path.Combine(dir1, "2.bmp");
                                            draw.Image(enemysDraw, fulldir1, enemy.tank);
                                        }
                                        else
                                        {
                                            fulldir1 = Path.Combine(dir1, "heavytank.bmp");
                                            draw.Image(enemysDraw, fulldir1, enemy.tank);
                                        }
                                    }; break;
                                case (down):
                                    {
                                        enemy.Direct = data.down;
                                        dir1 = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location);
                                        if (enemy.Type == data.light)
                                        {
                                            fulldir1 = Path.Combine(dir1, "4.bmp");
                                            draw.Image(enemysDraw, fulldir1, enemy.tank);
                                        }
                                        else
                                        {
                                            fulldir1 = Path.Combine(dir1, "hv2.bmp");
                                            draw.Image(enemysDraw, fulldir1, enemy.tank);
                                        }
                                    }; break;
                                case (left):
                                    {
                                        enemy.Direct = data.left;
                                        dir1 = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location);
                                        if (enemy.Type == data.light)
                                        {
                                            fulldir1 = Path.Combine(dir1, "5.bmp");
                                            draw.Image(enemysDraw, fulldir1, enemy.tank);
                                        }
                                        else
                                        {
                                            fulldir1 = Path.Combine(dir1, "hv3.bmp");
                                            draw.Image(enemysDraw, fulldir1, enemy.tank);
                                        }

                                    }; break;
                                case (right):
                                    {
                                        enemy.Direct = data.right;
                                        dir1 = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location);
                                        if (enemy.Type == data.light)
                                        {
                                            fulldir1 = Path.Combine(dir1, "3.bmp");
                                            draw.Image(enemysDraw, fulldir1, enemy.tank);
                                        }
                                        else
                                        {
                                            fulldir1 = Path.Combine(dir1, "hv1.bmp");
                                            draw.Image(enemysDraw, fulldir1, enemy.tank);
                                        }

                                    }; break;
                            }

                            enemy.tank = temp;
                            draw.MoveDraw(enemysDraw, enemy.tank, enemys.IndexOf(enemy));
                            enemy.trace.Remove(enemy.trace[enemy.trace.Count - 1]);

                        }
                        else
                        {
                            enemy.trace.Clear();
                            cleararray();
                           way(enemy.tank.Location.X, enemy.tank.Location.Y, enemys[0].tank.Location.X, enemys[0].tank.Location.Y, ref enemy.trace, enemys.IndexOf(enemy));

                        }
                    }
                    else
                    {
                        enemy.trace.Clear();
                        cleararray();
                         way(enemy.tank.Location.X, enemy.tank.Location.Y, enemys[0].tank.Location.X, enemys[0].tank.Location.Y, ref enemy.trace, enemys.IndexOf(enemy));

                    }

                }
            }
        }
    }
}
